package com.chenjt.customizePage.authentication;

import com.chenjt.customizePage.CustomizePageController;
import com.chenjt.customizePage.authentication.AuthenticationFailureHandler;
import com.chenjt.customizePage.imageCode.ImageCode;
import com.chenjt.customizePage.imageCode.ValidateCodeException;
import com.chenjt.customizePage.imageCode.ValidateResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;

/**
 * 注释：图片/短信验证码验证功能
 *
 * @author chenjt
 * @date 2025/1/26 17:23
 */
@Component
public class CodeValidateFilter extends OncePerRequestFilter implements InitializingBean {

    HttpSessionSessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

    @Autowired
    private AuthenticationFailureHandler authenticationFailureHandler;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        // 表单提交时才需要匹配校验码
        String requestURI = request.getRequestURI();

        // 表单提交
        if(requestURI.equals("/authentication/form")){
            ImageCode imageCode = (ImageCode) sessionStrategy.getAttribute(new ServletWebRequest(request), CustomizePageController.SESSION_KEY_IMAGE);

            // 表单提交的验证码
            String imageCodeFromRequest = ServletRequestUtils.getStringParameter(request, "imageCode");

            ValidateResult validateResult = validate(imageCodeFromRequest,imageCode);

            // 验证码校验不通过
            if(validateResult.getCode() != 0){// 0表示校验通过，其他都是校验不通过
                authenticationFailureHandler.onAuthenticationFailure(request,response,new ValidateCodeException(validateResult.getResult()));
                return;
            }

        }else if(requestURI.equals("/authentication/mobile")){

            ImageCode imageCode = (ImageCode) sessionStrategy.getAttribute(new ServletWebRequest(request), CustomizePageController.SESSION_KEY_SMS);

            // 表单提交的验证码
            String smsCodeFromRequest = ServletRequestUtils.getStringParameter(request, "smsCode");

            ValidateResult validateResult = validate(smsCodeFromRequest,imageCode);

            // 验证码校验不通过
            if(validateResult.getCode() != 0){// 0表示校验通过，其他都是校验不通过
                authenticationFailureHandler.onAuthenticationFailure(request,response,new ValidateCodeException(validateResult.getResult()));
                return;
            }

        }

        // 验证码校验通过或不是表单提交时放行
        filterChain.doFilter(request,response);


    }



    private ValidateResult validate(String imageCodeFromRequest, ImageCode imageCode) {

        if(StringUtils.isBlank(imageCodeFromRequest)){
            return new ValidateResult(1,"验证码不能为空");
        }

        if(imageCode == null){
            return new ValidateResult(2,"服务端未有校验码");
        }


        if(LocalDateTime.now().isAfter(imageCode.getExpireDateTime())){
            return new ValidateResult(3,"校验码过期");
        }


        if(!StringUtils.equals(imageCode.getCode(),imageCodeFromRequest)){
            return new ValidateResult(4,"校验码不匹配");
        }

        return new ValidateResult(0,"校验通过");

    }

}
